package inter.controller;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.alipay.api.RefundFastpayByPlatformNopwdApi;
import com.alipay.model.RefundFastpayByPlatformNopwdReq;
import com.dingpeikeji.quickdeer.core.modules.interfaces.entity.RealscheBackMoneyResult;
import com.dingpeikeji.quickdeer.core.modules.interfaces.entity.RealscheBookResult;
import com.dingpeikeji.quickdeer.core.modules.orders.entity.TOrders;
import com.dingpeikeji.quickdeer.core.modules.orders.entity.TOrdersOut;
import com.dingpeikeji.quickdeer.core.modules.orders.service.TOrdersOutService;
import com.dingpeikeji.quickdeer.core.modules.orders.service.TOrdersService;
import com.dingpeikeji.quickdeer.core.modules.payinfo.entity.TPayinfo;
import com.dingpeikeji.quickdeer.core.modules.payinfo.service.TPayinfoService;
import com.dingpeikeji.quickdeer.core.modules.realsche.entity.TRealsche;
import com.dingpeikeji.quickdeer.core.modules.sys.utils.UserUtils;
import com.dingpeikeji.quickdeer.modules.realsche.service.FRealscheService;
import com.dingpeikeji.quickdeer.modules.utils.ValidateTool;
import com.tencent.WXPay;
import com.tencent.common.Configure;
import com.tencent.protocol.refund_protocol.RefundReqData;

import inter.authorization.annotation.Authorization;
import inter.model.ResultModel;
/**
 * 实际班次操作接口
 * @author zijuan
 *
 */
@Controller
@RequestMapping(value = "api")
public class RealscheOperateController {
	@Autowired
	private FRealscheService fRealscheService;
	@Autowired
	private TPayinfoService tPayinfoService;
	@Autowired
	private TOrdersOutService tOrdersOutService;
	@Autowired
	private TOrdersService tOrdersService;
	
	 
	/**
	 * 实际班次查询
	 * @param tRealsche
	 * @return
	 * @throws ParseException 
	 */
	@RequestMapping(value = "realscheQuery")
	public ResponseEntity<ResultModel> realscheQuery(TRealsche realsche) throws ParseException {
		// ====================>>数据校验开始
		StringBuilder messages = new StringBuilder(); // 消息
		// 发车日期非空（默认当天），格式判断yyyy-MM-dd，不能小于今天
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String today = sdf.format(new Date()); // 当天日期字符串
		Date date = sdf.parse(today); // 今天日期
		String departdateStr = realsche.getDepartdateStr(); // 发车日期
		//String backDepartdateStr = realsche.getBackDepartdateStr(); // 返回日期
		String schetype = realsche.getSchetype(); // 车票类型
		if (ValidateTool.isEmptyOrNull(schetype)) {
			realsche.setSchetype("1"); // 如果车票类型为空，则默认是单程票
		}
		if (ValidateTool.isEmptyOrNull(departdateStr)) {
			realsche.setDepartdateStr(today);
		} else {
			try {
				Date departdate = sdf.parse(departdateStr);
				if(departdate.compareTo(date)<0){
					messages.append("发车日期不能小于今天");
				}
				/*if("2".equals(realsche.getSchetype())) { 
					// 比较下出发日期和返回日期
					try {
						Date backDepartdate = sdf.parse(backDepartdateStr);
						if(backDepartdate.compareTo(departdate)<0){
							messages.append("返回日期不能小于出发日期");
						}
					} catch (Exception e) {
						messages.append("返回日期格式非法（参照yyyy-MM-dd）");
					}
				}*/
			} catch (Exception e) {
				messages.append("发车日期格式非法（参照yyyy-MM-dd）");
			}
		}
		
		/*if (ValidateTool.isEmptyOrNull(backDepartdateStr)) {
			realsche.setBackDepartdateStr(today);
		}*/
		
		String boardaddr = realsche.getBoardaddr();
		if (ValidateTool.isEmptyOrNull(boardaddr)) {
			messages.append("出发站非空");
		}
		String offaddr = realsche.getOffaddr();
		if (ValidateTool.isEmptyOrNull(offaddr)) {
			messages.append("目的站非空");
		}
		/*if (ValidateTool.isEmptyOrNull(realsche.getBoardCitycode())) {
			messages.add("出发城市非空");
		}
		if (ValidateTool.isEmptyOrNull(realsche.getOffCitycode())) {
			messages.add("目的城市非空");
		}*/
		// ====================>>数据校验结束
		
		if(ValidateTool.isEmptyOrNull(messages.toString())) {//校验通过
			List<TRealsche> tRealscheList =  fRealscheService.findRealscheList(realsche);
			return new ResponseEntity<ResultModel>(ResultModel.ok(tRealscheList), HttpStatus.OK);//返回成功json
		}else{
			return new ResponseEntity<ResultModel>(ResultModel.no(messages), HttpStatus.OK);//返回失败json
		}
	}
	
	/**
	 * 班次车购票申请
	 * @param orders
	 * @return
	 */
	@RequestMapping(value = "realscheBooking")
	@Authorization
	public ResponseEntity<ResultModel> realscheMake(@RequestParam String userid,TOrders orders, String departdateStr, String boardCitycode, String offCitycode, String boardaddr, String offaddr){
		orders.setOrderuserid(userid);
		// ====================>>校验数据
		StringBuilder messages = new StringBuilder(); // 消息
		String realScheId = orders.getRealscheid();//实际班次ID
		if(ValidateTool.isEmptyOrNull(realScheId)){
			messages.append("实际班次ID非空");
		}
		String purchasenum = orders.getPurchasenum(); // 车辆数
		if(ValidateTool.isEmptyOrNull(purchasenum)){
			messages.append("车辆非空");
		} else if (!ValidateTool.isNonnegativeDigit(purchasenum)) {
			messages.append("车辆非负整数");
		}
		String contacts = orders.getContacts(); // 联系人
		String payertel = orders.getPayertel(); // 联系电话
		if(ValidateTool.isEmptyOrNull(contacts)){
			messages.append("联系人非空");
		}
		if(ValidateTool.isEmptyOrNull(payertel)){
			messages.append("联系电话非空");
		} else if(!ValidateTool.isMobile(payertel)) {
			messages.append("联系电话非法");
		}
		// ====================>>校验数据结束
		TRealsche realsche = new TRealsche();
		realsche.setRealscheid(orders.getRealscheid());
		realsche.setDepartdateStr(departdateStr);
		realsche.setBoardCitycode(boardCitycode);
		realsche.setOffCitycode(offCitycode);
		realsche.setBoardaddr(boardaddr);
		realsche.setOffaddr(offaddr);
		// 订单生成之前再判断下余票数量，有可能因为用户停留页面时间过长，导致余票不足
		realsche = fRealscheService.getRealscheOrderById(realsche);
		
		// 无需判断realsche为空，如果为空让页面报异常
		try {
			Integer leftSeats = Integer.parseInt(realsche.getLeftSeats());
			if(leftSeats==null || leftSeats<=0) {
				messages.append("对不起，余票不足，可能停留页面时间过长，请重新订票！");
			}
		} catch (NumberFormatException e) {
			messages.append("对不起，系统维护中，班次数据暂不可用！");
		}
		if (ValidateTool.isEmptyOrNull(messages.toString())) {//校验通过
			String message = fRealscheService.saveOrder(orders, realsche);
			TOrders order = tOrdersService.get(orders.getOrderid());
			//返回订单号、应付金额
			RealscheBookResult result = new RealscheBookResult(order.getOrderid(),order.getDueamount());
			if(message!=null){
				return new ResponseEntity<ResultModel>(ResultModel.no("购票申请失败"), HttpStatus.OK);
			} else {
				// 生成订单后调到支付页面
				return new ResponseEntity<ResultModel>(ResultModel.ok(result), HttpStatus.OK);
			}
		}
		return new ResponseEntity<ResultModel>(ResultModel.no(messages), HttpStatus.OK);

	}
	
	/**
	 * 班次车退票
	 * @param orders
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "realscheBackMoney")
	public ResponseEntity<ResultModel> realscheBackMoney(TOrders orders, HttpServletRequest request, HttpServletResponse response){
		
		TOrders torders = fRealscheService.getOrders(orders.getOrderid());
		// ==========>>数据校验
		StringBuilder messages = new StringBuilder(); // 消息
		Integer purchasenum = StringUtils.isEmpty(orders.getPurchasenum())?0:Integer.valueOf(orders.getPurchasenum());
		Integer childnum = StringUtils.isEmpty(orders.getChildnum())?0:Integer.valueOf(orders.getChildnum());
		Integer tpurchasenum = StringUtils.isEmpty(torders.getPurchasenum())?0:Integer.valueOf(torders.getPurchasenum());
		Integer tchildnum = StringUtils.isEmpty(torders.getChildnum())?0:Integer.valueOf(torders.getChildnum());
		if(purchasenum + childnum <= 0) {
			messages.append("退款数量至少为1张！");
		} else if(!(purchasenum <= tpurchasenum && childnum <= tchildnum)){
			messages.append("退票数量不正确！");
		} 
		// ==========>>数据校验结束
		if(ValidateTool.isEmptyOrNull(messages.toString())) {
			TPayinfo payinfo = new TPayinfo();
			payinfo.setOrders(orders);
			List<TPayinfo> payinfos = tPayinfoService.findList(payinfo);
			if(payinfos!=null && !payinfos.isEmpty()){
				Map<String,Object> result = fRealscheService.proCmptReturn(orders);
				Integer returnflag = (Integer) result.get("returnflag");
				if(returnflag!=null&&returnflag==0){
					payinfo = payinfos.get(0);
					String payway = torders.getPayway();
					//批次号，必填，格式：当天日期[8位]+序列号[3至24位]，如：201603081000001
					String batch_no = new SimpleDateFormat("yyyyMMdd").format(new Date())+UUID.randomUUID().toString().replace("-", "").substring(0, 16);
					//退款笔数，必填，参数detail_data的值中，“#”字符出现的数量加1，最大支持1000笔（即“#”字符出现的数量999个）
					String batch_num = "1";
					Double money = (Double) result.get("returnmoney");
					//退款详细数据，必填，格式（支付宝交易号^退款金额^备注），多笔请用#隔开
					String detail_data = payinfo.getFlowno() // 流水号就是支付宝单号
							+"^"+money+"^"
							+orders.getPurchasenum()+","+orders.getChildnum(); // 退款数量
					if(payway.equals(TOrders.PAY_WAY_ALIPAY)){ // 支付宝支付
						String refund_date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
						
						try {
							RefundFastpayByPlatformNopwdReq req = new RefundFastpayByPlatformNopwdReq(batch_no, refund_date, batch_num, detail_data);
							new RefundFastpayByPlatformNopwdApi().execute(req, request, response);
							// 保存退款信息
							TOrdersOut orderOut = new TOrdersOut();
							orderOut.setOrderid(Integer.parseInt(orders.getOrderid()));
							orderOut.setBatchNo(batch_no);
							orderOut.setOutnum(Integer.parseInt(orders.getPurchasenum()));
							orderOut.setRtnmoney(money);
							orderOut.setOutchildnum(Integer.parseInt(orders.getChildnum()));
							orderOut.setNotifyed(TOrdersOut.NOTIFED_NO);
							orderOut.setOutuserid(UserUtils.getUser().getId());
							orderOut.setRtnstatus(TOrdersOut.RTN_STATUS_FAIL);
							tOrdersOutService.save(orderOut);
							String outid = orderOut.getOutid().toString();
							float rtnmoney = orderOut.getRtnmoney().floatValue();
							RealscheBackMoneyResult results = new RealscheBackMoneyResult(outid,rtnmoney);
							return new ResponseEntity<ResultModel>(ResultModel.ok(results), HttpStatus.OK);
						} catch (Exception e) {
							messages.append("请求退款异常！");
						}
					}
					if(payway.equals(TOrders.PAY_WAY_WXPAY)){ // 微信支付
						String out_trade_no = "";
						for(int i=0;i<32-orders.getOrderid().length();i++){ // 补齐32位字符串
							out_trade_no+="0";
						}
						out_trade_no+=orders.getOrderid();
						RefundReqData refundReqData = new RefundReqData(""//payinfo.getFlowno()
								, out_trade_no, ""
								, batch_no
								, (int)(Double.valueOf(torders.getDueamount())*100)
								, (int)(Double.valueOf(money)*100)
								, Configure.getMchid()
								, "CNY");
						try {
							WXPay.requestRefundService(refundReqData);
							// 保存退款信息
							TOrdersOut orderOut = new TOrdersOut();
							orderOut.setOrderid(Integer.parseInt(orders.getOrderid()));
							orderOut.setBatchNo(batch_no);
							orderOut.setOutnum(Integer.parseInt(orders.getPurchasenum()));
							orderOut.setRtnmoney(money);
							orderOut.setOutchildnum(Integer.parseInt(orders.getChildnum()));
							orderOut.setNotifyed(TOrdersOut.NOTIFED_NO);
							orderOut.setOutuserid(UserUtils.getUser().getId());
							orderOut.setRtnstatus(TOrdersOut.RTN_STATUS_FAIL);
							tOrdersOutService.save(orderOut);
							fRealscheService.proConfirmRtn(batch_no);
							String outid = orderOut.getOutid().toString();
							float rtnmoney = orderOut.getRtnmoney().floatValue();
							RealscheBackMoneyResult results = new RealscheBackMoneyResult(outid,rtnmoney);
							return new ResponseEntity<ResultModel>(ResultModel.ok(results), HttpStatus.OK);
						} catch (Exception e) {
							messages.append("请求退款异常！");
						}
					}
				} else {
					messages.append((String) result.get("returnmsg"));
				}
			} else {
				messages.append("订单暂未生效！");
			}
		}
		return new ResponseEntity<ResultModel>(ResultModel.no(messages), HttpStatus.OK);

	}
	

}
